#!/usr/bin/env bun
// cli.ts
import { program } from "commander";
import * as fs from "fs";
import * as path from "path";
import { homedir } from "os";
import { spawn } from "child_process";

const STORAGE_DIR = path.join(homedir(), ".wplan", "storage");
fs.mkdirSync(STORAGE_DIR, { recursive: true });

interface Task {
  id: number;
  done: boolean;
  body: string;
  created: string;
}

/* ---------- 工具函数 ---------- */
function projectPath(name: string) {
  return path.join(STORAGE_DIR, `${name}.md`);
}

function loadProject(name: string): Task[] {
  const p = projectPath(name);
  if (!fs.existsSync(p)) return [];
  const raw = fs.readFileSync(p, "utf-8");
  return raw
    .split("\n")
    .filter((l) => l.startsWith("- [") || l.startsWith("- [x]"))
    .map((l) => {
      const done = l.startsWith("- [x]");
      const id = Number(l.match(/\[#(\d+)\]/)?.[1]);
      const body = l.replace(/^- \[[ x]\] \[#\d+\] /, "");
      const created = l.match(/\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]/)?.[1] || "";
      return { id, done, body, created };
    });
}

function saveProject(name: string, tasks: Task[]) {
  const lines = tasks.map(t => {
    const cleanBody = t.body.replace(/^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] /, '');
    return `- [${t.done ? 'x' : ' '}] [#${t.id}] [${t.created}] ${cleanBody}`;
  });
  fs.writeFileSync(projectPath(name), lines.join('\n') + '\n');
}

function nextId(): number {
  const all = fs
    .readdirSync(STORAGE_DIR)
    .filter((f) => f.endsWith(".md"))
    .flatMap((f) => loadProject(f.replace(/\.md$/, "")));
  return all.length ? Math.max(...all.map((t) => t.id)) + 1 : 1;
}

function listProjects() {
  return fs
    .readdirSync(STORAGE_DIR)
    .filter((f) => f.endsWith(".md"))
    .map((f) => f.replace(/\.md$/, ""));
}

function nowLocal() {
  const d = new Date();
  const yyyy = d.getFullYear();
  const mm   = String(d.getMonth() + 1).padStart(2, '0');
  const dd   = String(d.getDate()).padStart(2, '0');
  const hh   = String(d.getHours()).padStart(2, '0');
  const mi   = String(d.getMinutes()).padStart(2, '0');
  const ss   = String(d.getSeconds()).padStart(2, '0');
  return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}`;
}


/* ---------- 子命令 ---------- */
program
  .command("create <project> <text...>")
  .description("新建工作计划")
  .action((project, textArr) => {
    const text = textArr.join(" ");
    const tasks = loadProject(project);
    const id = nextId();
    tasks.push({ id, done: false, body: text, created: nowLocal() });
    saveProject(project, tasks);
    console.log(`[#${id}] 已添加到项目 ${project}`);
  });

program
  .command("view [project]")
  .option("-a, --all", "包含已完成")
  .description("查看某项目计划")
  .action((project, opts) => {
    if (!project) return console.error("需指定项目名");
    const tasks = loadProject(project);
    const filtered = opts.all ? tasks : tasks.filter((t) => !t.done);
    filtered.forEach((t) =>
      console.log(`[#${t.id}] ${t.done ? "[已完成] " : ""}${t.body}`)
    );
  });

program
  .command("list")
  .option("-a, --all", "包含已完成")
  .description("查看所有项目计划")
  .action((opts) => {
    listProjects().forEach((proj) => {
      const tasks = loadProject(proj);
      const filtered = opts.all ? tasks : tasks.filter((t) => !t.done);
      if (!filtered.length) return;
      console.log(`\n=== ${proj} ===`);
      filtered.forEach((t) =>
        console.log(`[#${t.id}] ${t.done ? "[已完成] " : ""}${t.body}`)
      );
    });
  });

program
  .command("done <id>")
  .description("完成某任务")
  .action((rawId) => {
    const id = Number(rawId);
    for (const proj of listProjects()) {
      const tasks = loadProject(proj);
      const t = tasks.find((x) => x.id === id);
      if (t) {
        t.done = true;
        saveProject(proj, tasks);
        console.log(`[#${id}] 标记为完成`);
        return;
      }
    }
    console.log(`[#${id}] 未找到`);
  });

program
  .command("edit <id> <text...>")
  .description("修改任务内容")
  .action((rawId, textArr) => {
    const id = Number(rawId);
    const newText = textArr.join(" ");
    for (const proj of listProjects()) {
      const tasks = loadProject(proj);
      const t = tasks.find((x) => x.id === id);
      if (t) {
        t.body = newText;
        saveProject(proj, tasks);
        console.log(`[#${id}] 已更新`);
        return;
      }
    }
    console.log(`[#${id}] 未找到`);
  });

program
  .command("plus <id> <text...>")
  .description("追加内容")
  .action((rawId, textArr) => {
    const id = Number(rawId);
    const append = textArr.join(" ");
    for (const proj of listProjects()) {
      const tasks = loadProject(proj);
      const t = tasks.find((x) => x.id === id);
      if (t) {
        t.body += " " + append;
        saveProject(proj, tasks);
        console.log(`[#${id}] 已追加`);
        return;
      }
    }
    console.log(`[#${id}] 未找到`);
  });

program
  .command("delete <id>")
  .description("删除任务")
  .action((rawId) => {
    const id = Number(rawId);
    for (const proj of listProjects()) {
      const tasks = loadProject(proj);
      const idx = tasks.findIndex((x) => x.id === id);
      if (idx !== -1) {
        tasks.splice(idx, 1);
        saveProject(proj, tasks);
        console.log(`[#${id}] 已删除`);
        return;
      }
    }
    console.log(`[#${id}] 未找到`);
  });

/* ---------- wplan open ---------- */
program
  .command("open [project]")
  .description("用 VS Code 打开 storage 目录或某个项目文件")
  .action((project) => {
    const target = project
      ? projectPath(project)
      : STORAGE_DIR;
    if (project && !fs.existsSync(target)) {
      console.error(`项目 ${project} 不存在`);
      process.exit(1);
    }
    spawn("code", [target], { stdio: "inherit", shell: true });
  });

/* ---------- wplan projects ---------- */
program
  .command("projects")
  .alias("proj")
  .description("列举所有项目名称")
  .action(() => {
    const list = listProjects();
    if (!list.length) return console.log("暂无项目");
    list.forEach((p) => console.log(p));
  });

program
  .action(() => {
    /* 用户没敲任何子命令时走到这里 */
    console.log('💡 输入 wplan -h 可查看全部命令帮助\n');
    const allProj = listProjects();
    if (!allProj.length) {
      console.log('暂无项目，快来创建第一个计划吧！');
      return;
    }
    for (const proj of allProj) {
      const tasks = loadProject(proj).filter(t => !t.done).slice(0, 10);
      if (!tasks.length) continue;
      console.log(`=== ${proj} ===`);
      tasks.forEach(t => console.log(`[#${t.id}] ${t.body}`));
    }
  });


program.parse(process.argv);
